package com.server;

import java.awt.Color;

import util.Util;

import com.exception.IllegalPackageException;
import com.packages.ClientPackageHandler;
import com.packages.PackageHandler;
import com.packages.ServerPackageHandler;
import com.sendables.Sendable;
import com.wrappers.Pair;
import com.wrappers.Returnable;

public class MessageHandler extends Thread {
	private ClientPackageHandler	cph;
	private ServerPackageHandler	sph;
	private UserPackageFilter		upf;
	private Monitor					m;
	private RoomHandler				roomHandler;
	private int						clientId;

	public MessageHandler(Monitor m, RoomHandler rh, ClientPackageHandler cph, ServerPackageHandler sph, int id,
			UserPackageFilter upf)
	{
		this.cph = cph;
		this.sph = sph;
		this.upf = upf;
		this.m = m;
		this.roomHandler = rh;
		clientId = id;
	}

	@SuppressWarnings("unchecked")
	public void run()
	{
		while (true)
		{
			byte[] b = m.getIncoming(clientId);
			int[] offset = new int[] { 4 };

			Returnable r = null;
			System.out.print("FROM " + clientId + ": ");
			try
			{
				r = cph.parse(b);
			} catch (IllegalPackageException e)
			{
				e.printStackTrace();
			}

			byte[] bAnswer = null;
			switch (b[offset[0]])
			{
				case ClientPackageHandler.ID:
					bAnswer = sph.prepare(PackageHandler.ID_ANS, Integer.toString(clientId));
					m.postOutgoing(bAnswer, clientId);
					break;
				case ClientPackageHandler.LIST_ROOM_REQ:
					bAnswer = sph.prepare(ServerPackageHandler.LIST_ROOM_ANS, roomHandler.getRooms());
					m.postOutgoing(bAnswer, clientId);
					break;
				case ClientPackageHandler.CREATE_ROOM_REQ:
					Pair<String, String> roomInfo = (Pair<String, String>) r;
					int createRoom = roomHandler.createRoom(roomInfo.getFirst(), roomInfo.getSecond());
					if (createRoom >= 0)
					{
						bAnswer = sph.prepare(PackageHandler.CREATE_ROOM_ANS, "true", Integer.toString(createRoom),
								roomInfo.getFirst());
					} else
					{
						bAnswer = sph.prepare(PackageHandler.CREATE_ROOM_ANS, "false");
					}
					m.postOutgoing(bAnswer, clientId);
					break;
				case ClientPackageHandler.JOIN_ROOM_REQ:
					Pair<Integer, String> p = (Pair<Integer, String>) r;
					boolean joinResult = roomHandler.join(p.getFirst(), clientId, p.getSecond());
					if (joinResult)
					{
						Color c = roomHandler.getColor(p.getFirst(), clientId);
						bAnswer = sph.prepare(ServerPackageHandler.JOIN_ROOM_ANS, "true", Integer.toString(c.getRGB()),
								Integer.toString(p.getFirst()));
					} else
					{
						bAnswer = sph.prepare(ServerPackageHandler.JOIN_ROOM_ANS, "false",
								Integer.toString(Color.blue.getRGB()), "-1");
					}
					m.postOutgoing(bAnswer, clientId);
					break;
				case ClientPackageHandler.SENDABLE:
					int roomId = roomHandler.findRoomOf(clientId);
					int sendableType = b[5];
					int[] ids = roomHandler.getMembersOfRoom(roomId);
					for (int i = 0; i < ids.length; i++)
					{
						boolean passPrefFilter = upf.passFilter(ids[i], sendableType);
						boolean dontSendToDispatcher = (sendableType != Sendable.CURSOR || ids[i] != clientId);
						if (passPrefFilter && dontSendToDispatcher)
						{
							m.postOutgoing(b, ids[i]);
						}
					}
					break;
				default:
					System.out.println("Unrecognized package {");
					Util.print(b, " ");
					System.out.println("} package ends");
			}
		}
	}
}
